//使用继承多态的思想，父类指向子类实现一个可以包容多种结构数据的容器。
#include <iostream>
#include <typeinfo>
#include <cassert>
#include <unistd.h>
#include <any>

class Any{
    private:
        class holder {
            public:
                virtual ~holder() {}
                virtual const std::type_info& type() = 0; //获取子类的数据类型
                virtual holder* clone() = 0;//克隆一个新的父类对象
        };
        template<class T>
        class placeholder:public holder {//子类
            public:
                placeholder(const T& val): _val(val) {}
                //获取子类的数据类型
                virtual const std::type_info& type() { return typeid(T); }
                
                //克隆一个新的子类对象
                virtual holder* clone() { return new placeholder(_val); }
            public:
                T _val;
        };
            holder *_content;
        public:
            Any(): _content(nullptr) {}//空类构造
            template<class T>
            Any(const T &val): _content(new placeholder<T>(val)) {}//构造任意类型数据的容器
            Any(const Any &other): _content(other._content ? other._content->clone() : nullptr) {}//根据其他通用容器构造新的容器
            ~Any() { delete _content; }

            Any &Swap(Any& other){
                std::swap(_content, other._content);
                return *this;
            }

            //获取子类对象中保存的数据指针
            template<class T>
            T *get() {
                assert(typeid(T) == _content->type()); //想要获取的数据类型必须和保存的数据类型一致
                return &((placeholder<T>*)_content)->_val;
            }

            //对空类容器或其他进行赋值
            template<class T>
            Any& operator=(const T &val) {
                //为val构造一个临时的通用容器，然后与当前容器自身进行指针交换，临时对象释放的时候，原保存的数据也就释放了
                Any(val).Swap(*this);
                return *this;
            }//赋值运算符重载函数(数据)
            Any& operator=(const Any &other){
                Any(other).Swap(*this);
                return *this;
            }//赋值运算符重载函数(容器)
};

class Test{
    public:
        Test() {std::cout << "构造" << std::endl;}
        Test(Test const &t) {std::cout << "拷贝构造" << std::endl;}
        ~Test() {std::cout << "析构" << std::endl;}
};

int main()
{
    // Any b;
    // {
    //     Test t;
    //     b = t;
    // }

    // Any a;
    // a = 10;
    // int *pa = a.get<int>();
    // std::cout << *pa << std::endl;
    // a = std::string("nihao");
    // std::string *ps = a.get<std::string>();
    // std::cout << *ps << std::endl;
    // return 0;

    std::any a;
    a = 10;
    int *pi = std::any_cast<int>(&a);
    std::cout << *pi << std::endl;
    return 0;

}
